﻿using CPAIS.Model;
using CPAIS.Updater;
using System;
using System.Xml;

namespace CPAIS.LogParser.PluginsWithXmlDocument
{
    /// <summary>
    /// Log parser for parsing event log file with XML Root TAG 'EventLog', like:
    /// 
    /// <EventLog>
    ///     <Case CP_ID="4" Visit_ID="8" OutPatient_ID="100351" InPatient_ID="117470" Diagnosis_Date="2011-11-26T14:50:00.000" Admit_Date="2011-11-26T14:07:16.000" Discharge_Date="2011-11-30T15:00:00.000" BirthDay="1935-06-23T00:00:00.000" Sex="男" Department="心血管内科三病区" Cost="51402.22">
    ///         <Event Type="Observation" ID="1" DateTime="2011-11-26 14:50:00" isNPL="False" Data="76" Unit="Years" Description="年龄" />
    ///         <Event Type="Action" ID="7" DateTime="2011-11-30 08:00:00" isNPL="False" Data="0.1" Unit="g" Description="阿司匹林肠溶片(拜耳-GE) 口服" />
    ///     </Case>
    /// </EventLog>
    /// 
    /// </summary>
    public class LogParserB : ILogParserWithXmlDocument
    {
        #region String used for parsing XML file
        private const string EventLog = "EventLog";
        private const string Case = "Case";
        private const string Visit_ID = "Visit_ID";
        private const string InPatient_ID = "InPatient_ID";
        private const string Admit_Date = "Admit_Date";
        private const string Discharge_Date = "Discharge_Date";
        private const string BirthDay = "BirthDay";
        private const string Sex = "Sex";
        private const string Department = "Department";
        private const string Cost = "Cost";
        private const string Event = "Event";
        private const string TypeL = "Type";
        private const string DateTimeL = "DateTime";
        private const string Description = "Description";

        private const string Male = "男";
        private const string Female = "女";
        private const string Observation = "Observation";
        private const string Action = "Action";
        #endregion

        public string XmlTag
        {
            get { return EventLog; }
        }

        public void Parse(LogModel logModel, XmlNode rootNode, StateUpdater updater)
        {
            foreach (XmlNode node in rootNode.ChildNodes)
            {
                if (node.Name != Case)
                    continue;

                string strPid = node.Attributes[InPatient_ID].Value.Trim();
                string strAdmitTime = node.Attributes[Admit_Date].Value.Trim();
                string strDischargeTime = node.Attributes[Discharge_Date].Value.Trim();
                string strBirthday = node.Attributes[BirthDay].Value.Trim();
                string strSex = node.Attributes[Sex].Value.Trim();
                string strDepartment = node.Attributes[Department].Value.Trim();
                string strCost = node.Attributes[Cost].Value.Trim();

                Trace trace = new Trace(logModel, strPid);
                trace.Admit = DateTime.Parse(strAdmitTime);
                trace.Discharge = DateTime.Parse(strDischargeTime);
                trace.Birthday = DateTime.Parse(strBirthday);
                trace.Sex = strSex == Male ? SexType.Male : (strSex == Female ? SexType.Female : SexType.Unknown);
                trace.Department = strDepartment;
                double cost;
                if (double.TryParse(strCost, out cost))
                    trace.Cost = cost;

                foreach (XmlNode sNode in node)
                {
                    if (sNode.Name == Event)
                    {
                        string strType = sNode.Attributes[TypeL].Value.Trim();
                        string strDateTime = sNode.Attributes[DateTimeL].Value.Trim();
                        string strDescription = sNode.Attributes[Description].Value.Trim();
                        DateTime timestamp = DateTime.Parse(strDateTime);
                        if (strType == Observation)
                        {
                            ObservationEvent entry = new ObservationEvent(trace, timestamp, strDescription);
                            trace.AddObservation(entry);
                        }
                        else if (strType == Action)
                        {
                            ActionEvent entry = new ActionEvent(trace, timestamp, strDescription);
                            trace.AddAction(entry);
                        }
                    }
                } 
                trace.OrderTrace();
                logModel.AddTrace(trace);
                if (updater != null)
                    updater.UpdateMessage(string.Format("{0} traces have been loaded...", logModel.TraceCount));
            }
        }
    }
}
